package production.practice.common.database.es;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
import production.practice.utils.IdGenerator;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * 
 * @author guojun
 *
 *
 */
public class ESUtil {

    private static Log logger = LogFactory.getLog(ESUtil.class);

    private static final SimpleDateFormat DF_DATETIME_NUM = new SimpleDateFormat("yyyyMMddHHmmss");

    private static final Object DF_DATETIME_NUM_SYNC = new Object();

    /**
     * <b>查询对象转化成Builder-不支持范围查询
     * 
     * @param e VMDB生成的查询对象
     * @return
     */
    public static BoolQueryBuilder cdtToBuilder(Object e) {
        BoolQueryBuilder querybuilder = QueryBuilders.boolQuery();
        try {
            Class<? extends Object> cls = e.getClass();
            Field[] fields = cls.getDeclaredFields();
            if (fields.length > 0) {
                Map<String, RangeQueryBuilder> rangeBuilderMap = new HashMap<String, RangeQueryBuilder>();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    field.setAccessible(true);
                    Class<?> type = field.getType();
                    String name = field.getName();
                    String simname = type.getSimpleName();
                    // 对字符串进行处理
                    if ("String".equals(simname)) {
                        String value = (String) field.get(e);
                        if (value != null && !"".equals(value) && name.endsWith("Equal")) {
                            querybuilder.filter(QueryBuilders.termQuery(name.replace("Equal", "") + ".keyword", value));
                        } else if (value != null && !"".equals(value) && !name.endsWith("Equal")) {
                            querybuilder.filter(QueryBuilders.multiMatchQuery(value.replaceAll("%", ""), name)
                                    .operator(Operator.AND).type(Type.PHRASE_PREFIX).lenient(true));
                        }
                    }
                    // 对Long和Integer处理，里面包含 start 和 end开头的字段
                    if ("Long".equals(simname) || "Integer".equals(simname)) {
                        Object value = field.get(e);
                        if (value != null && !name.startsWith("start") && !name.startsWith("end")) {
                            querybuilder.filter(QueryBuilders.termQuery(name, value));
                        } else if (value != null && name.startsWith("start")) {
                            char ch = name.substring(5).charAt(0);
                            String sourceName = ((char) (ch + 32)) + name.substring(6);
                            if (rangeBuilderMap.containsKey(sourceName)) {
                                RangeQueryBuilder range = rangeBuilderMap.get(sourceName);
                                range.from(value);
                            } else {
                                RangeQueryBuilder range = QueryBuilders.rangeQuery(sourceName);
                                range.from(value);
                                rangeBuilderMap.put(sourceName, range);
                            }
                        } else if (value != null && name.startsWith("end")) {
                            char ch = name.substring(3).charAt(0);
                            String sourceName = ((char) (ch + 32)) + name.substring(4);
                            if (rangeBuilderMap.containsKey(sourceName)) {
                                RangeQueryBuilder range = rangeBuilderMap.get(sourceName);
                                range.to(value);
                            } else {
                                RangeQueryBuilder range = QueryBuilders.rangeQuery(sourceName);
                                range.to(value);
                                rangeBuilderMap.put(sourceName, range);
                            }
                        }
                    }
                    // 对Long 和 Integer 的数组进行处理
                    if ("Integer[]".equals(simname)) {
                        Integer[] value = (Integer[]) field.get(e);
                        if (value != null) {
                            querybuilder.filter(QueryBuilders.termsQuery(name.substring(0, name.lastIndexOf("s")),
                                    Arrays.asList(value)));
                        }
                    }
                    if ("Long[]".equals(simname)) {
                        Long[] value = (Long[]) field.get(e);
                        if (value != null && value.length > 0) {
                            TermsQueryBuilder termsQuery = QueryBuilders
                                    .termsQuery(name.substring(0, name.lastIndexOf("s")), Arrays.asList(value));
                            querybuilder.filter(termsQuery);
                        }
                    }
                    // 对String类型的数据进行处理
                    if ("String[]".equals(simname)) {
                        String[] value = (String[]) field.get(e);
                        if (value != null && value.length > 0) {
                            querybuilder.filter(QueryBuilders.termsQuery(
                                    name.substring(0, name.lastIndexOf("s")) + ".keyword", Arrays.asList(value)));
                        }
                    }
                }
                if (rangeBuilderMap.size() > 0) {
                    Iterator<Entry<String, RangeQueryBuilder>> iter = rangeBuilderMap.entrySet().iterator();
                    while (iter.hasNext()) {
                        Entry<String, RangeQueryBuilder> entry = iter.next();
                        RangeQueryBuilder value = entry.getValue();
                        querybuilder.filter(value);
                    }
                }
            }
        } catch (Exception t) {
            logger.error(t.getMessage(), t);
        }
        logger.debug("querybuilder = " + querybuilder.toString());
        return querybuilder;
    }

    /**
     * <b>获取UUID
     * 
     * @return
     */
    public static long getUUID() {
        return IdGenerator.createGenerator().getID();
    }

    /**
     * <b>获取日期时间格式数值, 格式为：yyyyMMddHHmmss
     * 
     * @return
     */
    public static long getNumberDateTime() {
        return getNumberDateTime(new Date());
    }

    public static long getNumberDateTime(Date date) {
        synchronized (DF_DATETIME_NUM_SYNC) {
            return Long.parseLong(DF_DATETIME_NUM.format(date));
        }
    }

    static SimpleDateFormat DF_DATE_NUM = new SimpleDateFormat("yyyyMMdd");

    /**
     * 年月日
     * 
     * @return
     */
    public static long getNumberDate() {
        return Long.parseLong(DF_DATE_NUM.format(new Date()));
    }

    /**
     * 下划线 转 驼峰
     * 
     * @param param
     * @return
     */
    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        if (param.indexOf(" ") != -1) {
            String[] split = param.split(" ");
            param = split[0];
        }
        if (param.indexOf(",") != -1) {
            String[] split = param.split(",");
            param = split[0];
        }
        if (param.indexOf("_")==-1) {
            return param;
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = Character.toLowerCase(param.charAt(i));
            if (c == '_') {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}
